/**
 * 
 */
package com.wbcs.jbsf.util;

import java.io.IOException;
import java.io.StringWriter;
import java.security.MessageDigest;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.jackson.JsonFactory;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.map.ObjectMapper;

import com.wbcs.config.component.application.report.ReportBean;
import com.wbcs.jbsf.bean.Role;
import com.wbcs.jbsf.dao.IDataModal;
import com.wbcs.jbsf.dao.JBSFDaoTemplate;
import com.wbcs.jbsf.modal.abs.AbsTableSpaceModal;
import com.wbcs.system.ReportRequest;
import com.wbcs.system.assistant.EditableReportAssistant;
import com.wbcs.system.component.application.report.configbean.editablereport.AbsEditActionBean;
import com.wbcs.system.component.application.report.configbean.editablereport.AbsEditableReportEditDataBean;
import com.wbcs.system.component.application.report.configbean.editablereport.DeleteSqlActionBean;
import com.wbcs.system.component.application.report.configbean.editablereport.InsertSqlActionBean;
import com.wbcs.system.intercept.IInterceptor;

/**
 * @author hawkfly
 *
 */
public class Wbcs4JBSFUtil
{
    private static Log log = LogFactory.getLog(Wbcs4JBSFUtil.class);
    public static int doSavePerAction(ReportRequest rrequest,ReportBean rbean,Map<String,String> mRowData,Map<String,String> mParamValues,
            AbsEditActionBean actionbean,AbsEditableReportEditDataBean editbean, String dotparam, String[] lstCustomparams){
        String oldsql = null;
        if(actionbean instanceof InsertSqlActionBean){
            InsertSqlActionBean insertSqlActionBean = (InsertSqlActionBean)actionbean;
            oldsql = insertSqlActionBean.getSql();
        }else if(actionbean instanceof DeleteSqlActionBean){
            DeleteSqlActionBean deleteSqlActionBean = (DeleteSqlActionBean)actionbean;
            oldsql = deleteSqlActionBean.getSql();
        }else{
            return EditableReportAssistant.getInstance().doSavePerAction(rrequest,rbean,mRowData,mParamValues,actionbean,editbean);
        }
        if(oldsql.indexOf("in (") == -1)
            return EditableReportAssistant.getInstance().doSavePerAction(rrequest,rbean,mRowData,mParamValues,actionbean,editbean);
        String preoldsql = oldsql.substring(0, oldsql.indexOf("in ("));
        int precount = preoldsql.length() - preoldsql.replaceAll("\\?","").length();
        String sufoldsql = oldsql.substring(oldsql.indexOf(")",oldsql.indexOf("in (")));
        int sufcount = sufoldsql.length() - sufoldsql.replaceAll("\\?","").length();
        StringBuffer sb = new StringBuffer(preoldsql).append("in (");
        
        String dotstr = mRowData.get(dotparam);
        if(dotstr == null)
            return EditableReportAssistant.getInstance().doSavePerAction(rrequest,rbean,mRowData,mParamValues,actionbean,editbean);
        Object[] dotoary = dotstr.split(",");
        for(int i=0;i<dotoary.length;i++)
        {
            sb.append(" ? ,");
        }
        String tmpnewsql = sb.substring(0, sb.lastIndexOf(","));
        String newsql = new StringBuffer(tmpnewsql).append(sufoldsql).toString();
        
        JBSFDaoTemplate daoTemplate = new JBSFDaoTemplate(false);
        int effectRow = 0;
        if(lstCustomparams != null){
            Object[] params = new Object[precount];
            int paramscount = 0;
            for(int i = 0; i < precount; i++){//preparam
                paramscount = i+1;
                if(mParamValues != null && mParamValues.containsKey(lstCustomparams[i]))
                    params[i] = mParamValues.get(lstCustomparams[i]);
                else
                    params[i] = mRowData.get(lstCustomparams[i]);
            }
            params = concat(params, dotoary);
            Object[] sufparamsary = new Object[sufcount];
            params = concat(params, sufparamsary);
            for(int i = paramscount;i < paramscount + sufcount; i++)//sufparam
            {
                if(mParamValues != null && mParamValues.containsKey(lstCustomparams[i]))
                    params[dotoary.length + i] = mParamValues.get(lstCustomparams[i]);
                else
                    params[dotoary.length + i] = mRowData.get(lstCustomparams[i]);
            }
            try {
				effectRow = daoTemplate.update(newsql,rrequest.getConnection(),params);
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				try {
					rrequest.getConnection().rollback();
				} catch (SQLException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				return IInterceptor.WX_RETURNVAL_TERMINATE;
			}
        }else{
        	try {
        		effectRow = daoTemplate.update(newsql,rrequest.getConnection(),dotoary);
        	} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				try {
					rrequest.getConnection().rollback();
				} catch (SQLException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				return IInterceptor.WX_RETURNVAL_TERMINATE;
			}
        }
        
        if(effectRow != 0)return IInterceptor.WX_RETURNVAL_SUCCESS;
        else return IInterceptor.WX_RETURNVAL_TERMINATE;
    }
    
    public static String lst2dotStr(List<String> list){
        StringBuffer sb  = new StringBuffer();
        for(int i=0;i<list.size();i++)
        {
            sb.append("'"+list.get(i).trim()+"'").append(",");
        }
        if(sb.toString().equals(""))return "";
        return sb.substring(0, sb.lastIndexOf(","));
    }
    
    public static String ary2dotStr(String[] ary){
        StringBuffer sb  = new StringBuffer();
        for(int i=0;i<ary.length;i++)
        {
            sb.append(ary[i]).append(",");
        }
        if(sb.toString().equals(""))return "";
        return sb.substring(0, sb.lastIndexOf(","));
    }
    
    public static String lst2dotaskStr(int length){
        StringBuffer sb  = new StringBuffer();
        for(int i=0;i<length;i++)
        {
            sb.append("?,");
        }
        if(sb.toString().equals(""))return "";
        return sb.substring(0, sb.lastIndexOf(","));
    }
    
    public static void toclientPacket4TS(AbsTableSpaceModal tsmodal, Server2Client wca){
        for(Iterator<String> it = tsmodal.iterator(); it.hasNext();)
        {
            String locationtype = it.next();
            List<Map<String, Object>> lstmenus = tsmodal.getTable(locationtype).getAllstDatas2Collection();
            Object packetypeObj = lstmenus.get(0).get("packetype");
            if(packetypeObj == null){
                log.error(new StringBuffer("在方位类型表中name值为").append(locationtype).append("的类型为设定数据封装类型").toString());
                continue;
            }
            switch(Consts.PageMenusPackagingConst.valueOf(String.valueOf(packetypeObj))){
                case jcollection:
                    wca.write2ClientMenus(locationtype,lstmenus);
                case json:
                    ObjectMapper jsonMapper = JacksonMapper.getInstance();
                    StringWriter sw = new StringWriter();JsonGenerator gen;
                    try
                    {
                        gen=new JsonFactory().createJsonGenerator(sw);
                        jsonMapper.writeValue(gen, lstmenus); gen.close();
                    }catch(IOException e)
                    {
                        e.printStackTrace();
                    }
                    wca.write2ClientRs(sw.toString());
                    break;
                case xml:break;
                default:break;
            }
        }
        wca.close();
    }
    
    public static boolean isOk(String status){
        if(Consts.CONTINUE.equals(status))
            return true;
        else
            return false;
    }
    
    /**
     * List<Role> parse to List<rolecode>
     * @param roles
     * @param iscludeAdmin 是否排除管理员角色
     * @return
     */
    public static List<String> roles2lstrolecodes(List<Role> roles, boolean isexcludeAdmin){
        List<String> lstrolecodes = new ArrayList<String>();
        for(int i=0;i<roles.size();i++)
        {
            if(isexcludeAdmin && roles.get(i).isAdmin())continue;
            lstrolecodes.add(roles.get(i).getRolecode());
        }
        if(lstrolecodes.size() == 0)lstrolecodes.add("-1");
        return lstrolecodes;
    }
    
    /**
     * 将会话中的角色对象转换为角色名称字符串
     * @param roleObjs 会话中存储的角色对象
     * @return 角色名称字符串（逗号分隔）
     */
    public static String getRolenames(Object roleObjs){
        List lstRole = (List)roleObjs;
        StringBuffer rolenamesb = new StringBuffer("");
        for(int i = 0; i < lstRole.size(); i++){
            Role role = (Role)lstRole.get(i);
            rolenamesb.append(role.getRolename()).append(",");
        }
        String rolename = rolenamesb.substring(0, rolenamesb.lastIndexOf(","));
        return rolename;
    }
    
    /**
     * 数组合并
     * @param a array1
     * @param b array2
     * @return array1 + array2
     */
    public static Object[] concat(Object[] a, Object[] b) {
        Object[] c= new Object[a.length+b.length];
        System.arraycopy(a, 0, c, 0, a.length);
        System.arraycopy(b, 0, c, a.length, b.length);
        return c;
     }
    
    /**
     * 去除字符串结尾的所有逗号
     * @param str 原始字符串
     * @return 处理后的字符串
     */
    public static String removeTailComma(String str){
        if(str == null || str.length() == 0)return str;
        log.info("removeTailComma recursion...");
        str = str.trim();
        //如果字符串尾部不为逗号，返回字符串  
        if(!str.substring(str.length() -1).equals(",")){
            return str;  
        }else{  
            //否则将字符串尾部删除一位再进行递归  
            return removeTailComma(str.substring(0, str.length() -1 ));  
        }  
    }
    
    /**
     * 创建按照in条件顺序进行排序的sql order格式
     * @param orderCommaStr 逗号分隔的字符串
     * @param orderattr 排序字段的列名
     * @return 生成的sql order排序格式
     */
    public static String createSqlwhereinOrder(String orderCommaStr, String orderattr){
        if(orderCommaStr == null || orderattr == null)return null;
        StringBuffer tmpwherein = new StringBuffer(" order by decode(").append(orderattr).append(",");
        String[] orderCommaAry = orderCommaStr.split(",");
        String wherein = "";
        if(orderCommaAry.length <= 50){//资源数目小于50进行排序
            for(int i=0;i<orderCommaAry.length;i++)
            {
                tmpwherein.append("'").append(orderCommaAry[i]).append("', ").append(i+1).append(", ");
            }
            wherein = removeTailComma(tmpwherein.toString())+")";
        }
        return wherein;
    }
    
    /**
     * 对字符串进行4000临界值处理
     * @param srcstr 源字符串（多个值用逗号分隔）
     * @param splitedlst 根据4000临界值分隔的集合
     * @return 分隔后的临界集合
     */
    public static List<String> split4000(String srcstr, List<String> splitedlst){
        log.info("split4000 recursion...");
        if(srcstr.length() > 4000){
            String presrcstr = srcstr.substring(0,4001);
            int endidx = presrcstr.lastIndexOf(",");
            splitedlst.add(srcstr.substring(0, endidx));
            
            String sufsrcstr = srcstr.substring(endidx+1, srcstr.length());
            split4000(sufsrcstr, splitedlst);
        }else{
            splitedlst.add(srcstr);
        }
        return splitedlst;
    }
    
    /**
     * 广义空值判断方法，具体指：null值，空串，为null的字符串
     * @param param 待判断数据源
     * @return 是否为空
     */
    public static boolean isNull(String param){
        boolean b = false;
        if(param == null || "".equals(param.trim()) || "null".equalsIgnoreCase(param.trim()))
        {
            b = true;
        }
        return b;
    }
    
    /**
     * 获取MD5密文
     * @param srcstr 加密前字符串
     * @return MD5加密后的密文
     */
    public static String getmd5(String srcstr){
        char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
        try {
            byte[] btInput = srcstr.getBytes();
            // 获得MD5摘要算法的 MessageDigest 对象
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            // 使用指定的字节更新摘要
            mdInst.update(btInput);
            // 获得密文
            byte[] md = mdInst.digest();
            // 把密文转换成十六进制的字符串形式
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    
    /**
     * 获取指定序列的下一个值
     * @param conn 数据库连接对象
     * @param isclose 是否关闭连接
     * @param sequencename 序列名称
     * @return 序列的下一个值
     * @throws SQLException 
     */
    public static int getnextid(Connection conn, boolean isclose, String sequencename) throws SQLException{
        String executesql = "select " + sequencename + ".nextval from dual";
        JBSFDaoTemplate daotpl = new JBSFDaoTemplate(isclose);
        return daotpl.select(executesql,conn,new IDataModal<Integer>(){
            public Integer loadDatas(ResultSet rs,int ccount,ResultSetMetaData rmd,Integer dataModal) throws SQLException
            {
                while(rs.next()){
                   dataModal = rs.getInt(1);
                }
                return dataModal;
            }});
    }
}

